package com.sskj.api.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sskj.api.exception.LogicException;
import com.sskj.api.properties.SRSProperties;
import com.sskj.api.service.ISRSService;
import com.sskj.api.vo.srs.*;
import com.sskj.common.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SRSService implements ISRSService {

    @Autowired
    private SRSProperties srsProperties;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private DeviceService deviceService;

    @Override
    public Summaries summaries() {
        String url = srsProperties.getApiUrl() + "api/v1/summaries";
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()){
            if (response.isSuccessful() && response.body() != null) {
                String responseBody = response.body().string();
                if (!StrUtil.isBlank(responseBody)) {
                    JsonNode root = objectMapper.readTree(responseBody);
                    int code = root.get("code").asInt();
                    if (code == 0) {
                        Summaries summaries = new Summaries();

                        summaries.setServerName(root.get("server").asText());
                        long nowMs = root.get("data").get("now_ms").asLong();
                        LocalDateTime nowTime = Instant.ofEpochMilli(nowMs)
                                .atZone(ZoneId.of("Asia/Shanghai"))
                                .toLocalDateTime();
                        summaries.setNowTime(nowTime);

                        String selfJson = root.get("data").get("self").toString();
                        SummariesSelfInfo selfInfo = objectMapper.readValue(selfJson, SummariesSelfInfo.class);
                        summaries.setSummariesSelfInfo(selfInfo);

                        String systemJson = root.get("data").get("system").toString();
                        SummariesSystemInfo systemInfo = objectMapper.readValue(systemJson, SummariesSystemInfo.class);
                        summaries.setSummariesSystemInfo(systemInfo);

                        return summaries;
                    }
                }
            }
            log.error("[SRS流媒体服务]-请求异常。请求状态码:{}", response.code());
            throw new LogicException("请求失败");
        } catch (IOException e) {
            log.error("[SRS流媒体服务]-请求异常。异常信息:{}", e.getMessage());
            throw new LogicException("请求失败");
        }
    }

    @Override
    public List<ClientInfo> clients() {
        String url = srsProperties.getApiUrl() + "api/v1/clients";
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url)
                .build();
        List<ClientInfo> clientInfos = new ArrayList<>();
        try (Response response = okHttpClient.newCall(request).execute()){
            if (response.isSuccessful() && response.body() != null) {
                String respContent = response.body().string();
                if (StrUtil.isNotBlank(respContent)) {
                    JsonNode root = objectMapper.readTree(respContent);
                    int code = root.get("code").asInt();
                    if (code == 0) {
                        JsonNode clientsJsonNode = root.get("clients");
                        if (clientsJsonNode != null && clientsJsonNode.isArray()) {
                            clientInfos = objectMapper.convertValue(clientsJsonNode, new TypeReference<List<ClientInfo>>() {});
                        }
                    }
                }
            }
        } catch (IOException e) {
            log.error("[SRS流媒体服务]-请求异常。异常信息:{}", e.getMessage());
        }
        return clientInfos;
    }

    @Override
    public List<StreamInfo> streams() {
        String url = srsProperties.getApiUrl() + "api/v1/streams";
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url)
                .build();
        List<StreamInfo> streamInfos = new ArrayList<>();
        try (Response response = okHttpClient.newCall(request).execute()){
            if (response.isSuccessful() && response.body() != null) {
                String respContent = response.body().string();
                if (StrUtil.isNotBlank(respContent)) {
                    JsonNode root = objectMapper.readTree(respContent);
                    int code = root.get("code").asInt();
                    if (code == 0) {
                        JsonNode streamsJsonNode = root.get("streams");
                        if (streamsJsonNode != null && streamsJsonNode.isArray()) {
                            streamInfos = objectMapper.convertValue(streamsJsonNode, new TypeReference<List<StreamInfo>>() {});
                        }
                    }
                }
            }
        } catch (IOException e) {
            log.error("[SRS流媒体服务]-请求异常。异常信息:{}", e.getMessage());
        }
        return streamInfos;
    }

    @Override
    public List<VhostInfo> vhosts() {
        String url = srsProperties.getApiUrl() + "api/v1/vhosts";

        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url)
                .build();
        List<VhostInfo> vhostInfos = new ArrayList<>();
        try (Response response = okHttpClient.newCall(request).execute()){
            if (response.isSuccessful() && response.body() != null) {
                String respContent = response.body().string();
                if (StrUtil.isNotBlank(respContent)) {
                    JsonNode root = objectMapper.readTree(respContent);
                    int code = root.get("code").asInt();
                    if (code == 0) {
                        JsonNode vhostsJsonNode = root.get("vhosts");
                        if (vhostsJsonNode != null && vhostsJsonNode.isArray()) {
                            vhostInfos = objectMapper.convertValue(vhostsJsonNode, new TypeReference<List<VhostInfo>>() {});
                        }
                    }
                }
            }
        } catch (IOException e) {
            log.error("[SRS流媒体服务]-请求异常。异常信息:{}", e.getMessage());
        }
        return vhostInfos;
    }

    @Override
    public void destroyIdleStream() {
        List<ClientInfo> clients = clients();
        if (clients != null && !clients.isEmpty()) {
            // 已存在的视频流
            Set<String> streams = clients.stream().map(ClientInfo::getStream).collect(Collectors.toSet());

            for (ClientInfo clientInfo : clients) {
                if (!clientInfo.getPublish()) {
                    streams.remove(clientInfo.getStream());
                }
            }

            if (!streams.isEmpty()) {
                List<StreamInfo> streamsList = streams();
                for (String streamId : streams) {
                    String streamName = "";
                    for (StreamInfo item : streamsList) {
                        if (item.getId().equals(streamId)) {
                            streamName = item.getName();
                            break;
                        }
                    }

                    if (StrUtil.isNotBlank(streamName)) {
                        String[] split = streamName.split("_");
                        log.info("streamName={}", streamName);
                        if (split.length == 2) {
                            deviceService.stopVideo(split[0], Integer.valueOf(split[1]));
                        }
                    }
                }
            }
        }
    }
}
